namespace BadHabit.Factory.Reports
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Xml.XPath;
    using System.Xml.Xsl;

    /// <summary>
    /// Represents a generic report class. This is an abstract class.
    /// </summary>
    public abstract class Report
    {
        public string ProjectUId
        {
            get;
            set;
        }

        public string ProjectCategory
        {
            get;
            set;
        }

        protected FactoryLogic factory;

        public Report(FactoryLogic factory)
        {
            this.factory = factory;
        }

        /// <summary>
        /// The template type name. Should be overriden.
        /// </summary>
        public abstract string TemplateTypeName
        {
            get;
        }

        /// <summary>
        /// Adjusts the dastaset for XPS render.
        /// </summary>
        /// <param name="report">Report dataset</param>
        /// <returns>The adjusted dataset</returns>
        public virtual System.Data.DataSet AdjustDataSet(System.Data.DataSet report)
        {
            report.Namespace = string.Empty;
            report.EnforceConstraints = false;

            if (!report.Tables.Contains("General"))
            {
                report.Tables.Add("General");
            }

            report.Tables["General"].Columns.Add("TodayString", typeof(string));
            report.Tables["General"].Columns.Add("ServerURL", typeof(string));
            report.Tables["General"].Rows.Add(new object[] { DateTime.Now.ToLongDateString() + ", " + DateTime.Now.ToLongTimeString(), FactoryLogic.ServerUrl });

            return report;
        }

        /// <summary>
        /// Adjusts the dataset for XPS render.
        /// </summary>
        /// <param name="projectUId">The projectUId</param>
        /// <returns>The adjusted dataset</returns>
        public virtual System.Data.DataSet CreateDataSet()
        {
            return new System.Data.DataSet();
        }

        /// <summary>
        /// Retrives the template list.
        /// </summary>        
        public string[] RetriveTemplateList()
        {
            string path = FactoryLogic.ServerPath + ".\\App_Data\\ReportTemplates\\" + this.TemplateTypeName + "\\";
            string[] list = System.IO.Directory.GetFiles(path, "*.xslt");
            List<string> templateList = new List<string>();
            
            for (int i = 0; i < list.Length; i++)
            {
                string template = list[i].Substring(list[i].LastIndexOf("\\") + 1);
                if (!template.StartsWith("_"))
                {
                    templateList.Add(template);
                }
            }

            return templateList.ToArray();
        }

        public string GenerateFlowDocumentXAML(string templateName)
        {
            System.Data.DataSet report = this.CreateDataSet();
            return this.GenerateFlowDocumentXAML(report, templateName);
        }

        public string GenerateFlowDocumentXAML(System.Data.DataSet report, string templateName)
        {
            // Do this in order to avoid to change the original dataset
            System.Data.DataSet myReport = report.Copy();

            // adjust the report
            myReport = this.AdjustDataSet(myReport);

            // create the XPS file            
            string contextUri = FactoryLogic.ServerPath + ".\\";
            string xsltFileName = FactoryLogic.ServerPath + ".\\App_Data\\ReportTemplates\\" + this.TemplateTypeName + "\\" + templateName;

            // load the Xslt             
            XslCompiledTransform xslTrans = new XslCompiledTransform();
            xslTrans.Load(xsltFileName);

            // create the output stream           
            StringBuilder xaml = new StringBuilder();
            System.IO.StringWriter stringWriter = new System.IO.StringWriter(xaml);

            // do the actual transform of Xml            
            xslTrans.Transform(new XPathDocument(new System.IO.StringReader(myReport.GetXml())), null, stringWriter);

            return xaml.ToString();
        }

        /// <summary>
        /// Helper function for short dates.
        /// </summary>
        /// <param name="d">Any date</param>
        /// <returns>The Month and the day of the date</returns>
        public string MiniShortDateString(DateTime d)
        {
            string m = d.ToString("MMMM").Substring(0, 3);
            return d.Day + "-" + m;
        }
    }
}
